﻿using System;
using MosCraft.Utilities;

namespace MosCraft.Terrain.WorldGen
{
    class WorldGenLakes : WorldGenerator
    {
        private int block;

        public WorldGenLakes(int i)
        {
            block = i;
        }

        public override bool generate(World world, FastRandom rand, int x, int y, int z)
        {
            x -= 8;
            for (z -= 8; y > 0 && world.isAirBlock(x, y, z); y--) { }
            y -= 4;

            bool[] aflag = new bool[2048];
            int l = rand.nextInt(4) + 4;

            for (int i1 = 0; i1 < l; i1++)
            {
                double d = rand.nextDouble() * 6D + 3D;
                double d1 = rand.nextDouble() * 4D + 2D;
                double d2 = rand.nextDouble() * 6D + 3D;
                double d3 = rand.nextDouble() * (16D - d - 2D) + 1.0D + d / 2D;
                double d4 = rand.nextDouble() * (8D - d1 - 4D) + 2D + d1 / 2D;
                double d5 = rand.nextDouble() * (16D - d2 - 2D) + 1.0D + d2 / 2D;

                for (int j4 = 1; j4 < 15; j4++)
                {
                    for (int k4 = 1; k4 < 15; k4++)
                    {
                        for (int l4 = 1; l4 < 7; l4++)
                        {
                            double d6 = ((double)j4 - d3) / (d / 2D);
                            double d7 = ((double)l4 - d4) / (d1 / 2D);
                            double d8 = ((double)k4 - d5) / (d2 / 2D);
                            double d9 = d6 * d6 + d7 * d7 + d8 * d8;
                            if (d9 < 1.0D)
                            {
                                aflag[(j4 * 16 + k4) * 8 + l4] = true;
                            }
                        }

                    }

                }

            }

            for (int j1 = 0; j1 < 16; j1++)
            {
                for (int j2 = 0; j2 < 16; j2++)
                {
                    for (int j3 = 0; j3 < 8; j3++)
                    {
                        bool flag = !aflag[(j1 * 16 + j2) * 8 + j3] && (j1 < 15 && aflag[((j1 + 1) * 16 + j2) * 8 + j3] || j1 > 0 && aflag[((j1 - 1) * 16 + j2) * 8 + j3] || j2 < 15 && aflag[(j1 * 16 + (j2 + 1)) * 8 + j3] || j2 > 0 && aflag[(j1 * 16 + (j2 - 1)) * 8 + j3] || j3 < 7 && aflag[(j1 * 16 + j2) * 8 + (j3 + 1)] || j3 > 0 && aflag[(j1 * 16 + j2) * 8 + (j3 - 1)]);
                        
                        if (!flag)
                        {
                            continue;
                        }

                        Material material = world.getBlockMaterial(x + j1, y + j3, z + j2);

                        //if (material == Material.Air)
                        //{
                        //    return false;
                        //}

                        if (j3 >= 4 && material.getIsLiquid())
                        {
                            return false;
                        }

                        if (j3 < 4 && !material.getIsSolid() && world.getBlockID(x + j1, y + j3, z + j2) != block)
                        {
                            return false;
                        }
                    }

                }

            }

            for (int k1 = 0; k1 < 16; k1++)
            {
                for (int k2 = 0; k2 < 16; k2++)
                {
                    for (int k3 = 0; k3 < 8; k3++)
                    {
                        if (aflag[(k1 * 16 + k2) * 8 + k3])
                        {
                            world.setBlockID(x + k1, y + k3, z + k2, k3 < 4 ? block : 0);
                        }
                    }

                }

            }

            for (int l1 = 0; l1 < 16; l1++)
            {
                for (int l2 = 0; l2 < 16; l2++)
                {
                    for (int l3 = 4; l3 < 8; l3++)
                    {
                        if (aflag[(l1 * 16 + l2) * 8 + l3] && world.getBlockID(x + l1, (y + l3) - 1, z + l2) == Block.Dirt.blockID)
                        {
                            world.setBlockID(x + l1, (y + l3) - 1, z + l2, Block.Grass.blockID);
                        }
                    }

                }

            }

            return true;
        }


    }
}
